﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.Common.Locator;

using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Web.ApplicationRuntime;

namespace Fuse8.ContentManagementFramework.Web.MvcPowered
{
    public static class CmsUserGroupPlaceholderExtension
    {
        public static CmsUserGroupPlaceholder UserGroupPlaceholder(this HtmlHelper htmlHelper, object htmlAttributes = null)
        {
            return new CmsUserGroupPlaceholder(htmlHelper).Attributes(htmlAttributes);
        }
    }
    
    public class CmsUserGroupPlaceholder : CmsMvcBaseComponent<CmsUserGroupPlaceholder, CmsUser>
    {
        private CmsUser _contextUser;
        private IMembershipService _membershipService = DependencyServiceLocator.Current.GetInstance<IMembershipService>();
        
        protected IEnumerable<string> InnnerForUserGroups { get; set; }

        protected Func<CmsUser, object> AlternativeInlineTemplate { get; set; }

        public CmsUserGroupPlaceholder(HtmlHelper htmlHelper)
            : this(DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextUser, htmlHelper)
        { }
        
        public CmsUserGroupPlaceholder(CmsUser user, HtmlHelper htmlHelper)
            : base(htmlHelper)
        {
            Guard.ArgumentNotNull(user, "user");

            _contextUser = user;

            Component = this;
        }

        public CmsUserGroupPlaceholder ForUserGroups(string userGroups)
        {
            if (userGroups != null)
            {
                InnnerForUserGroups = userGroups.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }
            
            return this;
        }

        public CmsUserGroupPlaceholder AlternativeTemplate(Func<CmsUser, object> template)
        {
            if (template != null)
            {
                AlternativeInlineTemplate = template;
            }

            return this;
        }

        protected virtual string RenderAlternativeTemplate()
        {
            return AlternativeInlineTemplate != null ?
                AlternativeInlineTemplate(Value).ToString() : //TO DO: think about SetInnerHtml() method, but here is html encoding issue
                string.Empty;
        }

        protected override string RenderComponent()
        {
            bool isGrantedAccess = false;

            if ((InnnerForUserGroups != null) && InnnerForUserGroups.Any())
            {
                foreach (var userGroupName in InnnerForUserGroups)
                {
                    isGrantedAccess = _membershipService.IsUserInGroup(_contextUser.LoginName, userGroupName);
                    if (!isGrantedAccess)
                    {
                        break;
                    }
                }
            }

            return isGrantedAccess ?
                RenderTemplate() :
                RenderAlternativeTemplate();
        }
    }
}
